// pages/music-player/index.js
// import { getSongDetail, getSongLyric } from "../../service/api_player"
import {
  audioContext,
  playerStore
} from "../../../store/index"
// import { parseLyric } from "../../utils/index"

const playModeNames = ["order", "repeat", "random"]

Page({

  /**
   * 页面的初始数据
   */
  data: {
    id: 0,
    currentSong: {},

    currentPage: 0,
    contentHeight: 0,
    isMusicLyric: true,

    durationTime: 0,
    currentTime: 0,
    sliderValue: 0,
    isSliderChanging: false,

    lyricInfos: [],
    currentLyricIndex: 0,
    currentLyricText: "",
    lyricScrollTop: 0,

    playModeIndex: 0,
    playModeName: "order",
    isPlaying: false,
    playingName: "pause"
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    // 1.获取传入的id
    const id = options.id
    this.setData({
      id
    })

    // 2.根据id获取歌曲信息（已抽取，不再使用）
    // this.getPageData(id)
    // 采用从 store 中获取数据
    this.setupPlayStoreListener()

    // 3.动态计算内容高度（去全局app.js中）
    const globalData = getApp().globalData
    const screenHeight = globalData.screenHeight
    const statusBarHeight = globalData.statusBarHeight
    const navBarHeight = globalData.navBarHeight

    // 计算导航栏高度
    const contentHeight = screenHeight - statusBarHeight - navBarHeight
    // 设备高宽比
    const deviceRadio = globalData.deviceRadio

    this.setData({
      contentHeight,
      isMusicLyric: deviceRadio >= 2
    })

    // 4.使用audioContext播放歌曲（创建播放器已放置全局store同时播放逻辑也放入store）
    // 播放先停止上一首
    // audioContext.stop()
    // audioContext.src = `https://music.163.com/song/media/outer/url?id=${id}.mp3`
    // 自动播放
    // audioContext.autoplay = true

    // 5.audioContext的事件监听（已抽取放入store）
    // this.setupAudioContextListener()
  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {
    playerStore.offStates(["currentSong", "durationTime", "lyricInfos"], this.handleCurrentMusicListener)
    playerStore.offStates(["currentTime", "currentLyricIndex", "currentLyricText"], this.handleCurrentLyricListener)
    playerStore.offStates(["playModeIndex", "isPlaying"], this.handleCurrentPlayingListener)
  },

  // ========================   网络请求（已抽取） ========================
  // 已经不再使用，已抽取，并放到了 store 中
  getPageData: function (id) {
    getSongDetail(id).then(res => {
      // console.log(res);
      this.setData({
        currentSong: res.songs[0],
        durationTime: res.songs[0].dt
      })
    })

    getSongLyric(id).then(res => {
      // console.log(res.lrc.lyric);
      const lyricString = res.lrc.lyric
      const lyrice = parseLyric(lyricString)
      // console.log(lyrice);
      this.setData({
        lyricInfos: lyrice
      })
    })
  },

  // ========================   事件监听（已抽取） ========================
  setupAudioContextListener() {
    // 监听歌曲可以播放，用户手动跳动后，也可触发
    audioContext.onCanplay(() => {
      audioContext.play()
    })

    // 监听播放进度，更新事件
    audioContext.onTimeUpdate(() => {
      // 1.获取播放当前进度时间（API获取到的是秒s，需要转成毫秒ms，用于界面显示）Math.ceil
      const currentTime = audioContext.currentTime * 1000

      // 2.根据当前时间修改 currentTime/sliderValue
      if (!this.data.isSliderChanging) {
        // 播放slider的值（当前时长 / 总时长）
        const sliderValue = currentTime / this.data.durationTime * 100

        this.setData({
          currentTime,
          sliderValue
        })
      }

      // 3.根据当前时间去查找播放的歌词
      // 当没有歌词，直接返回
      if (!this.data.lyricInfos.length) return
      let i = 0
      for (; i < this.data.lyricInfos.length; i++) {
        // 获取当前索引歌词对象
        const lyricInfo = this.data.lyricInfos[i]

        if (currentTime < lyricInfo.time) {
          break
        }
      }

      // 设置当前歌词的索引和内容
      const currentIndex = i - 1
      if (this.data.currentLyricIndex !== currentIndex) {
        const currentLyricInfo = this.data.lyricInfos[currentIndex]
        const currentLyricText = currentLyricInfo.text
        // console.log(currentLyricText);

        // 歌词的滚动距离
        const lyricScrollTop = currentIndex * 35

        this.setData({
          currentLyricText,
          currentLyricIndex: currentIndex,
          lyricScrollTop
        })
      }
    })
  },

  // ========================   事件处理   ========================
  // 详情页的分页
  handleSwiperChange: function (event) {
    // console.log(event);
    const current = event.detail.current
    this.setData({
      currentPage: current
    })
  },
  // 滑动块的点击触发
  handleSliderChange: function (event) {
    // 1.获取点击slider变化的值
    const value = event.detail.value

    // 2.计算需要播放的currentTime (总时长*(value/100)加不加括号都一样)
    const currentTime = this.data.durationTime * value / 100

    // 3.设置context播放currentTime位置的音乐（先暂停，在播放）
    // audioContext.pause()
    // seek默认是s，需要转成ms
    audioContext.seek(currentTime / 1000)

    // 4.记录最新的sliderValue，并且需要将isSliderChanging设置回false
    this.setData({
      sliderValue: value,
      isSliderChanging: false
    })
  },
  // 滑动块的滑动触发
  handleSliderChanging: function (event) {
    // 1.获取滑动slider变化的值
    const value = event.detail.value

    // 2.计算滑动后的currentTime
    const currentTime = this.data.durationTime * value / 100

    // 3.松手后会自动触发 handleSliderChange 事件，因此这里不用做播放处理，
    //   统一在 handleSliderChange 中做 isSliderChanging 处理

    // 这里不能设置，sliderValue: value, 页面设置是同步的，但是页面更新是异步的，会出现来回跑
    this.setData({
      isSliderChanging: true,
      currentTime
    })
  },
  // 返回按钮事件
  handleBackBtnClick: function () {
    wx.navigateBack()
  },
  // 播放模式事件
  handleModeBtnClick: function () {
    // 计算最新的playModeIndex
    let playModeIndex = this.data.playModeIndex + 1
    if (playModeIndex === 3) playModeIndex = 0

    // 设置playerStore中的playModeIndex
    playerStore.setState("playModeIndex", playModeIndex)
  },
  // 播放与暂停
  handlePlayBtnClick: function () {
    playerStore.dispatch("changeMusicPlayStatusAction", !this.data.isPlaying)
  },
  // 上一首
  handlePrevBtnClick: function () {
    playerStore.dispatch("changeNewMusicAcion", false)
  },
  handleNextBtnClick: function () {
    playerStore.dispatch("changeNewMusicAcion")
  },

  // ========================   数据监听(store获取)   ========================
  setupPlayStoreListener: function () {
    // 监听共享数据一 currentSong/durationTime/lyricInfos
    playerStore.onStates(["currentSong", "durationTime", "lyricInfos"], this.handleCurrentMusicListener)
    // 监听共享数据二 currentTime/currentLyricIndex/currentLyricText
    playerStore.onStates(["currentTime", "currentLyricIndex", "currentLyricText"], this.handleCurrentLyricListener)
    // 监听播放模式相关的数据（可补增列表）
    playerStore.onStates(["playModeIndex", "isPlaying"], this.handleCurrentPlayingListener)
  },

  // 数据监听数据抽取，用于卸载
  handleCurrentMusicListener: function ({
    currentSong,
    durationTime,
    lyricInfos
  }) {
    if (currentSong) this.setData({
      currentSong
    })
    if (durationTime) this.setData({
      durationTime
    })
    if (lyricInfos) this.setData({
      lyricInfos
    })
  },
  handleCurrentLyricListener: function ({
    currentTime,
    currentLyricIndex,
    currentLyricText
  }) {
    // 时间变化
    if (currentTime && !this.data.isSliderChanging) {
      // 当前页面逻辑：播放slider的值（当前时长 / 总时长）
      const sliderValue = currentTime / this.data.durationTime * 100
      this.setData({
        currentTime,
        sliderValue
      })
    }
    // 歌词变化
    if (currentLyricIndex) {
      // 当前页面逻辑：歌词的滚动距离
      const lyricScrollTop = currentLyricIndex * 35
      this.setData({
        currentLyricIndex,
        lyricScrollTop
      })
    }
    // 处理好的歌词
    if (currentLyricText) this.setData({
      currentLyricText
    })
  },
  handleCurrentPlayingListener: function ({
    playModeIndex,
    isPlaying
  }) {
    if (playModeIndex !== undefined) {
      const playModeName = playModeNames[playModeIndex]
      this.setData({
        playModeIndex,
        playModeName
      })
    }
    if (isPlaying !== undefined) {
      this.setData({
        isPlaying,
        playingName: isPlaying ? "pause" : "resume"
      })
    }
  },
})